{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Using the DeepMIMO Dataset with Sionna\n",
    "\n",
    "In this example, you will learn how to use the ray-tracing based DeepMIMO dataset."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[DeepMIMO](https://deepmimo.net/) is a generic dataset that enables a wide range of machine/deep learning applications for MIMO systems. It takes as input a set of parameters (such as antenna array configurations and time-domain/OFDM parameters) and generates MIMO channel realizations, corresponding locations, angles of arrival/departure, etc., based on these parameters and on a ray-tracing scenario selected [from those available in DeepMIMO](https://deepmimo.net/scenarios/).\n",
    "\n",
    "## Table of Contents\n",
    "* [GPU Configuration and Imports](#GPU-Configuration-and-Imports)\n",
    "* [Configuration of DeepMIMO](#Configuration-of-DeepMIMO)\n",
    "* [Using DeepMIMO with Sionna](#Using-DeepMIMO-with-Sionna)\n",
    "* [Link-level Simulations using Sionna and DeepMIMO](#Link-level-Simulations-using-Sionna-and-DeepMIMO)\n",
    "* [DeepMIMO License and Citation](#DeepMIMO-License-and-Citation)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## GPU Configuration and Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-03-13T01:48:42.830858Z",
     "iopub.status.busy": "2025-03-13T01:48:42.830249Z",
     "iopub.status.idle": "2025-03-13T01:48:45.899584Z",
     "shell.execute_reply": "2025-03-13T01:48:45.898771Z"
    }
   },
   "outputs": [],
   "source": [
    "import os\n",
    "if os.getenv(\"CUDA_VISIBLE_DEVICES\") is None:\n",
    "    gpu_num = 0 # Use \"\" to use the CPU\n",
    "    os.environ[\"CUDA_VISIBLE_DEVICES\"] = f\"{gpu_num}\"\n",
    "os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'\n",
    "\n",
    "# Import Sionna\n",
    "try:\n",
    "    import sionna.phy\n",
    "except ImportError as e:\n",
    "    import sys\n",
    "    if 'google.colab' in sys.modules:\n",
    "       # Install Sionna in Google Colab\n",
    "       print(\"Installing Sionna and restarting the runtime. Please run the cell again.\")\n",
    "       os.system(\"pip install sionna\")\n",
    "       os.kill(os.getpid(), 5)\n",
    "    else:\n",
    "       raise e\n",
    "\n",
    "# Configure the notebook to use only a single GPU and allocate only as much memory as needed\n",
    "# For more details, see https://www.tensorflow.org/guide/gpu\n",
    "import tensorflow as tf\n",
    "gpus = tf.config.list_physical_devices('GPU')\n",
    "if gpus:\n",
    "    try:\n",
    "        tf.config.experimental.set_memory_growth(gpus[0], True)\n",
    "    except RuntimeError as e:\n",
    "        print(e)\n",
    "# Avoid warnings from TensorFlow\n",
    "tf.get_logger().setLevel('ERROR')\n",
    "\n",
    "sionna.phy.config.seed = 42 # Set seed for reproducible random number generation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-03-13T01:48:45.903639Z",
     "iopub.status.busy": "2025-03-13T01:48:45.903247Z",
     "iopub.status.idle": "2025-03-13T01:48:45.914833Z",
     "shell.execute_reply": "2025-03-13T01:48:45.913951Z"
    }
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "# Load the required Sionna components\n",
    "from sionna.phy import Block\n",
    "from sionna.phy.mimo import StreamManagement\n",
    "from sionna.phy.ofdm import ResourceGrid, ResourceGridMapper, LSChannelEstimator, \\\n",
    "                            LMMSEEqualizer, RZFPrecoder, RemoveNulledSubcarriers\n",
    "from sionna.phy.channel import subcarrier_frequencies, ApplyOFDMChannel, \\\n",
    "                               GenerateOFDMChannel, CIRDataset\n",
    "from sionna.phy.fec.ldpc import LDPC5GEncoder, LDPC5GDecoder\n",
    "from sionna.phy.mapping import BinarySource, Mapper, Demapper\n",
    "from sionna.phy.utils import ebnodb2no, sim_ber\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Configuration of DeepMIMO"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "DeepMIMO provides multiple [scenarios](https://deepmimo.net/scenarios/) that one can select from. In this example, we use the O1 scenario with the carrier frequency set to 60 GHz (O1_60). To run this example, please download the \"O1_60\" data files [from this page](https://deepmimo.net/scenarios/o1-scenario/). The downloaded zip file should be extracted into a folder, and the parameter `DeepMIMO_params['dataset_folder']` should be set to point to this folder, as done below.\n",
    "\n",
    "To use DeepMIMO with Sionna, the DeepMIMO dataset first needs to be generated. The generated DeepMIMO dataset contains channels  for different locations of the users and basestations. The layout of the O1 scenario is shown in the figure below. \n",
    "\n",
    "![O1_top_view]()\n",
    "\n",
    "In this example, we generate a dataset that consists of channels for the links from the basestation 6 to the users located on the rows 400 to 450. Each of these rows consists of 181 user locations, resulting in $51 \\times 181 = 9231$ basestation-user channels.\n",
    "\n",
    "The antenna arrays in the DeepMIMO dataset are defined through the x-y-z axes. In the following example, a single-user MISO downlink is considered. The basestation is equipped with a uniform linear array of 16 elements spread along the x-axis. The users are each equipped with a single antenna. These parameters can be configured using the code below (for more information about the DeepMIMO parameters, please check [the DeepMIMO configurations](https://deepmimo.net/versions/v2-python/))."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-03-13T01:48:45.918949Z",
     "iopub.status.busy": "2025-03-13T01:48:45.918713Z",
     "iopub.status.idle": "2025-03-13T01:48:52.133244Z",
     "shell.execute_reply": "2025-03-13T01:48:52.132383Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting DeepMIMO\n",
      "  Downloading DeepMIMO-1.0-py3-none-any.whl.metadata (421 bytes)\n",
      "Requirement already satisfied: numpy in /usr/local/lib/python3.10/site-packages (from DeepMIMO) (1.26.4)\n",
      "Requirement already satisfied: scipy in /usr/local/lib/python3.10/site-packages (from DeepMIMO) (1.15.2)\n",
      "Collecting tqdm (from DeepMIMO)\n",
      "  Downloading tqdm-4.67.1-py3-none-any.whl.metadata (57 kB)\n",
      "Downloading DeepMIMO-1.0-py3-none-any.whl (21 kB)\n",
      "Downloading tqdm-4.67.1-py3-none-any.whl (78 kB)\n",
      "Installing collected packages: tqdm, DeepMIMO\n",
      "Successfully installed DeepMIMO-1.0 tqdm-4.67.1\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Basestation 6\n",
      "\n",
      "UE-BS Channels\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "BS-BS Channels\n"
     ]
    }
   ],
   "source": [
    "# Import DeepMIMO\n",
    "try:\n",
    "    import DeepMIMO\n",
    "except ImportError as e:\n",
    "    # Install DeepMIMO if package is not already installed\n",
    "    import os\n",
    "    os.system(\"pip install DeepMIMO\")\n",
    "    import DeepMIMO\n",
    "\n",
    "# Channel generation\n",
    "DeepMIMO_params = DeepMIMO.default_params() # Load the default parameters\n",
    "DeepMIMO_params['dataset_folder'] = r'./scenarios' # Path to the downloaded scenarios\n",
    "DeepMIMO_params['scenario'] = 'O1_60' # DeepMIMO scenario\n",
    "DeepMIMO_params['num_paths'] = 10 # Maximum number of paths\n",
    "DeepMIMO_params['active_BS'] = np.array([6]) # Basestation indices to be included in the dataset\n",
    "\n",
    "# Selected rows of users, whose channels are to be generated.\n",
    "DeepMIMO_params['user_row_first'] = 400 # First user row to be included in the dataset\n",
    "DeepMIMO_params['user_row_last'] = 450 # Last user row to be included in the dataset\n",
    "\n",
    "# Configuration of the antenna arrays\n",
    "DeepMIMO_params['bs_antenna']['shape'] = np.array([16, 1, 1]) # BS antenna shape through [x, y, z] axes\n",
    "DeepMIMO_params['ue_antenna']['shape'] = np.array([1, 1, 1]) # UE antenna shape through [x, y, z] axes\n",
    "\n",
    "# The OFDM_channels parameter allows choosing between the generation of channel impulse\n",
    "# responses (if set to 0) or frequency domain channels (if set to 1).\n",
    "# It is set to 0 for this simulation, as the channel responses in frequency domain\n",
    "# will be generated using Sionna.\n",
    "DeepMIMO_params['OFDM_channels'] = 0\n",
    "\n",
    "# Generates a DeepMIMO dataset\n",
    "DeepMIMO_dataset = DeepMIMO.generate_data(DeepMIMO_params)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Visualization of the dataset\n",
    "\n",
    "To provide a better understanding of the user and basestation locations, we next visualize the locations of the users, highlighting the first active row of users (row 400), and basestation 6."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-03-13T01:48:52.136681Z",
     "iopub.status.busy": "2025-03-13T01:48:52.136424Z",
     "iopub.status.idle": "2025-03-13T01:48:52.372533Z",
     "shell.execute_reply": "2025-03-13T01:48:52.371889Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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6dChQ4n7c9ddd5m//e1v5sUXXzTR0dEmMjLSPPjggyX+bJg8eXKxfZg8ebL7vXz33XdNz549TUhIiKlTp4755JNPPF6/fv1607VrV1O+fHkTFRVl7rjjDrN79+4S6z/5ffvJJ5+Yhg0bGn9/f7Nt2zazZ88ec+edd5qIiAgTEhJiunbtajZv3myMMaaoqMhUrlzZ4/ulefPmJjo62v182bJlJigoyBw6dMgUFRWZESNGmLi4OBMUFGRiYmLMQw89VOr7aowxffr0McOGDTMjRowwzZs395h31VVXeXxfFBYWmtjYWDNu3DhjjDH79u0zgYGBHjVmZWUZSSY9Pd3r9tq3b1/svT/pww8/dH9P1qhRw0yYMOGM9Z9pH06fVlhYaPbu3WsKCwvPeR+MMebFF180rVq18ph2cmzs3bvXPW3evHlGkvnuu+88lj1w4ICpW7euSU1NLfZzxkpNCxYsMH5+fmbnzp3uZSZNmmTCw8NNfn6+15pPf9/bt2/vfk9GjRplLr/8chMUFGSaN29uPvvssxL33Zj/H3Onuvnmm018fHyxZRcsWGAaNGhgNm7caCSZtWvXuudt27at2LTT9e7d2/To0cNjWps2bcx9993nMe3uu+82d9xxR4nrKe0z8GQO3b9/f4mvN8YYjrQDAAD8SU8//bReeuklrVmzRgEBAfrHP/7hnrds2TL169dPDz/8sDZt2qS3335bKSkpeu655855e2vWrNGgQYM0evRoZWdna+HChWrXrp17/rhx4zR16lS99dZb2rhxox555BHdcccdWrJkicd6nnjiCY0fP15ZWVlq1qyZ+vbtq2rVqmn16tXKyMjQE088ocDAQEs1HTp0SN26dVNERIRWrlyp2bNn68svv1RycrJ7mUmTJikpKUn33nuv1q9fr3nz5qlOnTru+X5+fpo4caI2btyoKVOmaNGiRXrsscckSVdffXWxMx5Onu2QnJys9PR0zZgxQ+vWrdOtt96qrl27asuWLZKklStXasCAAUpOTlZmZqY6dOigZ5999oz706VLF1122WVavXq11/2RpMWLF2vr1q1avHix+6hjSkqK13X26dNHQ4cO9TgC26dPH/f8UaNGqXfv3lq3bp26d++uvn37as+ePZJOHNW97rrrFB8frzVr1mjhwoX67bff1Lt371L34/Dhw3r++ef13nvvaePGjYqKilL//v21Zs0azZs3T+np6TLGqHv37iooKJDL5VK7du2UlpYmSdq7d6+ysrJ05MgRff/995KkJUuWqHXr1goNDdWcOXPcRzu3bNmijz/+WE2bNi21psmTJ+vHH3/0enT02LFjysjIUKdOndzT/Pz81KlTJ6Wnp0uSMjIyVFBQ4LFMgwYNVL16dfcyp/voo49UrVo1jR492v3en1xX79699fe//13r16/XyJEjNXz48BK/hlb24aQtW7YoNjZWtWvX1h133KEdO3a4553LPkgnfp60atWq1Nr279+vGTNmSJKCgoI85iUlJalHjx4e2z2bmtLT09W0aVNVrVrVvUyXLl2Ul5enjRs3eq3n5KUNJ49qf/TRR5Kk1157TS+99JImTJigdevWqUuXLrrxxhvd49aKDRs2aMWKFcX287ffftPAgQP13//+V6GhoSW+/sYbb1RUVJSuueYazZs3z2Neenp6sfepS5cuxb4+V111lZYtW2a55nNSaqS/RHCkHfCOo4mAd4yNs3OpHGk/6dNPPzWS3PvbsWNHM3bsWI/X/fe//zUxMTElbu9MR9rnzJljwsPDTV5eXrHXHj161ISGhpoVK1Z4TB8wYIC57bbbPOr++OOPPZYJCwszKSkpJdZ1Op1ypP2dd94xl112mfn555/dRxM//fRTj6NysbGx5umnn7a8/tmzZ5tKlSq5n3v7Ovz000/G39/f/PLLLx7TO3bsaJ588kljjDG33Xab6d69u8f8Pn36lHqk/eT+HDx40D3t9P256667TI0aNczx48fdy9x6662mT58+Ja7X21FZY068l8OGDXM/P3jwoJHkPvI4ZswY07lzZ4/X7Nixw0gy2dnZXrd18sh+Zmame9rmzZuNJLN8+XL3tN9//92EhISYWbNmGWOMmThxomncuLEx5sRZIm3atDF/+9vfzKRJk4wxxnTq1Mk89dRTxpgTZ0fUq1fP8s/DzZs3m6ioKHfNp78fv/zyi5FU7Pv30UcfNVdddZUxxphp06aZoKCgYutu3bq1eeyxx0rcdo0aNcwrr7ziMe322283119/fbFtNWrU6Jz3wZgTR3lnzZplvvvuO7Nw4UKTkJBgqlWrZvbt2/en9qF58+Zm9OjRHtNOjufy5cub8uXLu49o33jjjR7LffDBB6ZJkybun02n/5yxUtPAgQOLfR8eOnTIfeaONyUd1Y6NjTXPPfdcsW09+OCDJe7/XXfdZfz9/U358uVNcHCwkWT8/PzMhx9+6F6mqKjIdO3a1YwZM6bE7e/evdu89NJL5ptvvjGrVq0yjz/+uHG5XB5ntwQGBprp06d7bP/NN980UVFRHtM++eQT4+fn5/65dzqOtAMAgEvOxl/3q+YTn2rjr/t9XYrbqdeGxsTESJL7+tvvvvtOo0ePVoUKFdyPgQMHKjc3V4cPHz6n7V1//fWqUaOGateurTvvvFPTpk1zr+uHH37Q4cOHdf3113tsc+rUqdq6davHek4/YjdkyBDdc8896tSpk8aPH19s+dJkZWWpefPmKl++vHta27ZtVVRUpOzsbO3atUu//vpridf/SieOxHXs2FGXX365wsLCdOedd+qPP/4o9X1av369CgsLVa9ePY/9XbJkibv+rKwstWnTxuN1CQkJf2p/TmrcuLH8/f3dz2NiYjyuvT4bp34flS9fXuHh4R7fR4sXL/bYxwYNGkhSqV+noKAgj/VmZWUpICDA4/2oVKmS6tevr6ysLElS+/bttWnTJu3evVtLlixRYmKiEhMTlZaWpoKCAq1YsUKJiYmSpFtvvVVHjhxR7dq1NXDgQM2dO7fE/giFhYW6/fbbNWrUKNWrV++c3qOylpWVpbZt23pMa9u2rbZs2aLCwsJiy1vdh27duunWW29Vs2bN1KVLF82fP1/79+/XrFmz/lS9R44cUbly5bzOW7ZsmTIyMpSSkqJ69erprbfecs/bsWOHHn74YU2bNq3E19spLy9Pv/76q9f3/uT3YUk6dOigzMxMrVy5UnfddZfuvvtu9erVyz3/9ddf14EDB/Tkk0+WuI7KlStryJAhatOmjVq3bq3x48frjjvu0IsvvnjW+xISEqKioiLl5+ef9WutCjhvawYAADgPekz82v3v9vE9fFzNCaeeQu5yuSTJ3fDr4MGDGjVqlNcGUyX98uzn5ydjjMe0goIC9//DwsL07bffKi0tTV988YWeeeYZjRw5UqtXr9bBgwclSZ9++qkuv/xyj3UEBwd7PD81kEonOl7ffvvt+vTTT/XZZ59pxIgRmjFjhm666aZS99+KkJCQUudv375df/3rX/XAAw/oueeeU2RkpL7++msNGDBAx44dK/EU14MHD8rf318ZGRke4VmSKlSo8KfrPpPTLx9wuVzn3OyttHUdPHhQN9xwg55//vlirzv5hyJvQkJC3N+TVjVt2lSRkZFasmSJlixZoueee07R0dF6/vnntXr1ahUUFOjqq6+WJMXFxSk7O1tffvmlUlNT9eCDD+rFF1/UkiVLiu3PgQMHtGbNGq1du9Z9mUFRUZGMMQoICNAXX3yha665Rv7+/sU6lv/222+Kjo6WJEVHR+vYsWPat2+fx90ETl3mfLGyD9ddd12x10VERKhOnTruP7Cc6z5UrlxZe/fu9TqvVq1aioiIUP369bVr1y716dNHS5culXTi1Pddu3apZcuW7uULCwu1dOlSvfHGG8rPz7dUU3R0dLFO/ie/Vuf7vT+pfPny7stq/vOf/6h58+b697//rQEDBkiSFi1apPT09GI/71q1aqW+fftqypQpXtfbpk0bpaamup9HR0eX+n140p49e1S+fPkz/oz7MzjSDgAALiifDrrG41+na9mypbKzs1WnTp1iDz8/77+KValSxX3NrXTil+tTOxZLUkBAgDp16qQXXnhB69at0/bt27Vo0SI1atRIwcHBysnJKba9uLi4M9Zbr149PfLII/riiy908803a/LkyZb2s2HDhvruu+906NAh97Tly5fLz89P9evXV1hYmGrWrKmvvvrK6+szMjJUVFSkl156SX/5y19Ur149/frrrx7LBAUFFTv6GR8fr8LCQu3atavY/p785bphw4ZauXKlx+tOv7XT2e7PufK2D1a0bNlSGzduVM2aNYvt5+l/fClNw4YNdfz4cY/3448//lB2drYaNWok6cQfC6699lp98skn2rhxo6655ho1a9ZM+fn5evvtt9WqVSuPbYaEhOiGG27QxIkTlZaWpvT0dK+3GwsPD9f69euVmZnpftx///2qX7++MjMz1aZNGwUFBenKK6/0+D4pKirSV1995T474sorr1RgYKDHMtnZ2crJySn1DApv733Dhg21fPlyj2nLly9XvXr1iv0RyOo+eHPw4EFt27bN/QeWc92H+Ph4bdq0qcT5JyUlJWnDhg2aO3euJKljx47F6j4ZYjMzM+Xv72+ppoSEBK1fv97jbJLU1FSFh4e7v39Od/J681Pf+/DwcMXGxnp970tajzd+fn566qmnNGzYMB05ckSSNHHiRH333Xfu/Tx5m7aZM2eW2kskMzPT4w9gCQkJxX5epaamFvv6bNiwQfHx8ZZrPielnjx/ibhQrmk/UnDE7D682xwpuHCvCcSFhet2Ae8YG2fnUrim/dSuzWvXrjWSzLZt24wxxixcuNAEBASYkSNHmg0bNphNmzaZDz74oNRru9966y0TGhpq5s+fb7KysszAgQNNeHi4+5r2//3vf+a1114za9euNdu3bzf/+te/jJ+fn9mwYYMxxpinn37aVKpUyaSkpJgffvjBZGRkmIkTJ7qvV/dW9+HDh01SUpJZvHix2b59u/n666/NFVdcUer1tTrlmvZDhw6ZmJgYc+ONN5rvvvvOLFq0yNSuXduj431KSoopV66cee2118zmzZvddRlzovO8JPPqq6+arVu3mqlTp5rLL7/co87ly5e7ewjs3r3bHDp0yBhjTN++fU3NmjXNnDlzzI8//mhWrlxpxo4da+bPn2+MMSY9Pd34+fmZF1980WzevNm8/vrrJiIiotRr2k/uT69evcz69eu97o+3TtYPP/ywuzu2N9OmTTPly5c3a9euNbt37zZHjx4t9l6eVLFiRXd3+V9++cVUqVLF3HLLLWbVqlXmhx9+MAsXLjT9+/f3uKb+VCV93/7tb38zjRo1MsuWLTOZmZmma9eupk6dOh4/01599VXj7+9v2rRp4/E6f39/88QTT3hs47333jPr1683W7duNcOGDTMhISGWf6/2dj34jBkzTHBwsElJSTGbNm0y9957r4mIiPDoWH7//feb6tWrm0WLFpk1a9aYhIQEk5CQUOq2rr/+enPjjTean3/+2d11PyMjw/j5+ZnRo0eb7Oxsk5KSYkJCQtzv+7nuw9ChQ01aWprZtm2bWb58uenYsaOpVKnSn96HefPmmaioKI+vubfxbIwxjz32mGnatKkpKiryui5vvTPOVNPx48dNkyZNTOfOnU1mZqZZuHChqVKlirt/hDcFBQUmJCTEPPvss2bnzp3u6/pfeeUVEx4ebmbMmGG+//578/jjj5vAwED3nQy88TbmCgoKzOWXX25efPFFr6/xdk17SkqKmT59usnKyjJZWVnmueeeM35+fuY///mPe5nly5ebgIAAM2HCBJOVlWVGjBhhAgMDzfr164u9j6f3GThVWVzTTmg3zg/tGTszzMOLHjbNpjQzTVKamGZTmpmHFz1svv3tW1+XhoscwQTwjrFxdi710G7MieB+9dVXm5CQEBMeHm6uuuoq884775S4vWPHjpkH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vHlzXX755cXmRUVFKTo6Wi1bttTgwYO1Y8cO9/t40sGDB9W3b1+9++67uuyyyzzm7d+/X//+97/18ssv67rrrtOVV16pyZMna8WKFfrmm28kSV988YU2bdqk999/Xy1atFC3bt00ZswYvfnmmx5/ILjhhhs0b948HTlypMR9AXBxIbQDAACUkQkTJqh58+Zau3athg8frokTJ2revHmaNWuWsrOzNW3aNHc4X716tSRp8uTJys3NdT8vyRNPPKGHH35YWVlZ6tKli1577TW99NJLmjBhgtatW6cuXbroxhtv1JYtWyRJ7du3V1pamvv1S5YsUeXKld3TVq9erYKCAl199dVet5eRkaHevXvr73//u9avX6+RI0dq+PDhSklJkSR99NFHGjhwoBISEpSbm6uPPvronN6z3Nxc3XbbbfrHP/6hrKwspaWl6eabb5YxRpI0bdo0PfPMM3ruueeUlZWlsWPHavjw4ZoyZUqp709SUpLy8/O1dOlSrV+/Xs8//7wqVKhQYh3Lli1Tq1atSq11//79mjFjhqQTR71PlZSUpB49eqhTp07FXpeRkaGCggKPeQ0aNFD16tWVnp4uSUpPT1fTpk1VtWpV9zJdunRRXl6eNm7c6J7WqlUrHT9+XCtXriy1VgAXDxrRAQAAlGL+/PkeYa9bt26aPXu212Wvu+46DR061P08JydHdevW1TXXXCOXy6UaNWq451WpUkWSFBERoejo6DPWMXjwYI/TqSdMmKDHH39cf//73yVJzz//vBYvXqxXX31Vb775phITE/Xwww9r9+7dCggI0KZNmzR8+HClpaXp/vvvV1pamlq3bq3Q0FCv23v55ZfVsWNHDR8+XJJUr149bdq0SS+++KL69++vyMhIhYaGKigoyF1/UVHRGffjdLm5uTp+/Lhuvvlm9/vTtGlT9/wRI0bopZdecu97rVq1tGnTJr399tu66667Snx/cnJy1KtXL/e6ateuXWodP/30U4mhvVq1apLkPvp/4403qkGDBu75M2bM0LffflviH1527typoKAgRUREeEyvWrWqdu7c6V7m1MB+cv7JeSeFhoaqYsWK+umnn0rdHwAXD460AwCAC0vuOmlkxRP/2qBDhw7KzMx0P0q7nvj00Ne/f39lZmaqfv36GjRokL744otzruPUdefl5enXX39V27ZtPZZp27atsrKyJElNmjRRZGSklixZomXLlik+Pl5//etftWTJEkknjryXdEq7JGVlZXld/5YtW1RYWHjO+3G65s2bq2PHjmratKluvfVWvfvuu9q7d6+kEyF569atGjBggCpUqOB+PPvss9q6davHek5/7wcNGqRnn31Wbdu21YgRI7RuXenfL0eOHFG5ct6b/S5btkwZGRlKSUlRvXr19NZbb7nn7dixQw8//LCmTZtW4uvLWkhIiA4fPmzLtgD4HqEdAABcWN6+1vPf86x8+fKqU6eO+xETE1Pqsqdq2bKltm3bpjFjxujIkSPq3bu3brnllnOu42y4XC61a9dOaWlp7oDerFkz5efna8OGDVqxYoXat29/TrWcDT8/P/ep7ied2ijO399fqamp+uyzz9SoUSO9/vrrql+/vrZt26aDBw9Kkt59912PP5xs2LDBfS34Sae/P/fcc49+/PFH3XnnnVq/fr1atWql119/vcQ6K1eu7P5jwelq1aql+vXr66677tI999yjPn36uOdlZGRo165datmypQICAhQQEKAlS5Zo4sSJCggIUGFhoaKjo3Xs2DHt27fPY72//fab+yyF6OjoYt3kTz4//UyMPXv2uM/UAHDxI7QDAIALy33LPP91uPDwcPXp00fvvvuuZs6cqTlz5mjPnj2SpMDAwHM6ah0eHq7Y2FgtX77cY/ry5cvVqFEj9/OT17WnpaUpMTFRfn5+ateunV588UXl5+cXO5J+qoYNG3pdf7169eTv72+51ipVqig3N9djWmZmpsdzl8ultm3batSoUVq7dq2CgoI0d+5cVa1aVbGxsfrxxx89/nBSp04d1apV64zbjouL0/3336+PPvpIQ4cO1bvvvlvisvHx8dq0adMZ15mUlKQNGzZo7ty5kqSOHTtq/fr1Hn9UaNWqlfr27avMzEz5+/vryiuvVGBgoL766iv3erKzs5WTk6OEhARJUkJCgtavX69du3a5l0lNTVV4eLjH13Tr1q06evSo4uPjz1grgIsD17QDAIALS0wzaeR+X1dhycsvv6yYmBjFx8fLz89Ps2fPVnR0tPva5po1a+qrr75S27ZtFRwcXKzreGkeffRRjRgxQldccYVatGihyZMnKzMzU9OmTXMvk5iYqEceeURBQUG65ppr3NP++c9/qnXr1qUevR86dKhat26tMWPGqE+fPkpPT9cbb7zh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OwCUEU6PBwAAjnX0+FEt3rG41MAunTjivmjHovPSnK5Dhw7KzMxUZmamVq1apS5duqhbt2766aefJEkzZ85U27ZtFR0drQoVKmjYsGHKyclxv37IkCG655571KlTJ40fP15bt251z/vuu++UkpKiChUquB9dunRRUVGRtm3bpuuvv141atRQ7dq1deedd2ratGk6fPjwGWt+8803deWVV6pKlSqqUKGC3nnnHY+arMjKylJCQoJcLpd7Wtu2bXXw4EH9/PPP7mnNmjXzeF3VqlW1a9eus9oWAKBkhHYAAOBYBwsOuq9hP5MiU6SDBQfLvIby5curTp06qlOnjlq3bq333ntPhw4d0rvvvqv09HT17dtX3bt31/z587V27Vo9/fTTOnbsmPv1I0eO1MaNG9WjRw8tWrRIjRo10ty5c0/s38GDuu+++9x/FMjMzNR3332nLVu26IorrlBYWJi+/fZbffDBB4qJidEzzzyj5s2ba9++fSXWO2PGDP3zn//UgAED9MUXXygzM1N33323R01l6eSp/ie5XC4VFVn7mgEAzozT4wEAgGNVCKwgP5efpeDu5/JThcAK570ml8slPz8/HTlyRCtWrFCNGjX09NNPu+efPAJ/qnr16qlevXp65JFHdNttt2ny5Mm66aab1LJlS23atEl16tQpcXsBAQHq1KmTOnXqpBEjRigiIkKLFi3SzTffrKCgIBUWep6FsHz5cl199dV68MEH3dNOPbovyevrTtewYUPNmTNHxhj30fbly5crLCxM1apVK/W1AICyw5F2AADgWOUCyqlDXAf5u/xLXc7f5a/r4q5TuYByZV5Dfn6+du7cqZ07dyorK0sPPfSQDh48qBtuuEF169ZVTk6OZsyYoa1bt2rixInuo+iSdOTIESUnJystLU0//fSTli9frtWrV6thw4aSTnSeX7FihZKTk5WZmaktW7bok08+UXJysqQT19NPnDhRmZmZ+umnnzR16lQVFRWpfv36kk5cQ79y5Upt375dv//+u4qKilS3bl2tWbNGn3/+uTZv3qzhw4dr9erVHvtUs2ZNrVu3TtnZ2fr99989ut2f9OCDD2rHjh166KGH9P333+uTTz7RiBEjNGTIEPf17ACA84+fuAAAwNH6Nep3xiPtRaZI/Rr3Oy/bX7hwoWJiYhQTE6M2bdpo9erVmj17thITE3Xj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S8WpHbL53AD+3+l3UuBzA2Xlog3txhjzv//9zzRp0sQEBwebBg0amHfeecdjflFRkRk+fLipWrWqCQ4ONh07djTZ2dkey/zxxx/mtttuMxUqVDDh4eHm7rvvNgcOHLBzN4Ay1adPHxMTE2OCgoLM5Zdfbvr06WN++OEHY4wxOTk5pl27diYyMtIEBwebOnXqmEcffdTs37/fYx3bt2833bp1MyEhIaZy5cpm6NChpqCgwBe7A5SZ0saGMcYcOXLEPPjgg+ayyy4zoaGh5qabbjK5ubke62Bs4FJwajDhcwP4f6eHdj43UFZcxhjj66P9AAAAAACguIv2mnYAAAAAAC50hHYAAAAAAByK0A4AAAAAgEMR2gEAAAAAcChCOwAAAAAADkVoBwAAAADAoQjtAAAAAAA4FKEdAADYwuVy6eOPP/Z1GQAAXFACfF0AAAC4NOTm5uqyyy7zdRkAAFxQXMYY4+siAAAAAABAcZweDwDAJWbq1KmqVKmS8vPzPab37NlTd955p9fX/Pe//1WrVq0UFham6Oho3X777dq1a5d7/ujRoxUbG6s//vjDPa1Hjx7q0KGDioqKJHmeHn/s2DElJycrJiZG5cqVU40aNTRu3Lgy3lMAAC58hHYAAC4xt956qwoLCzVv3jz3tF27dunTTz/VP/7xD6+vKSgo0JgxY/Tdd9/p448/1vbt29W/f3/3/Kefflo1a9bUPffcI0l68803tWLFCk2ZMkV+fsV/3Zg4caLmzZunWbNmKTs7W9OmTVPNmjXLdD8BALgYcE07AACXmJCQEN1+++2aPHmybr31VknS+++/r+rVqysxMdHra04N87Vr19bEiRPVunVrHTx4UBUqVJC/v7/ef/99tWjRQk888YQmTpyo9957T9WrV/e6vpycHNWtW1fXXHONXC6XatSoUeb7CQDAxYAj7QAAXIIGDhyoL774Qr/88oskKSUlRf3799f06dNVoUIF92PZsmWSpIyMDN1www2qXr26wsLC1L59e0knwvdJtWvX1oQJE/T888/rxhtv1O23317i9vv376/MzEzVr19fgwYN0hdffHEe9xYAgAsXR9oBALgExcfHq3nz5po6dao6d+6sjRs36tNPP1VERITatGnjXu7yyy/XoUOH1KVLF3Xp0kXTpk1TlSpVlJOToy5duujYsWMe6126dKn8/f21fft2HT9+XAEB3n/VaNmypbZt26bPPvtMX375pXr37q1OnTrpww8/PK/7DQDAhYbQDgDAJeqee+7Rq6++ql9++UWdOnVSXFycJCksLMxjuYyMDP3xxx8aP368e5k1a9YUW9/MmTP10UcfKS0tTb1799aYMWM0atSoErcfHh6uPn36qE+fPrrlllvUtWtX7dmzR5GRkWW4lwAAXNg4PR4AgEvU7bffrp9//lnvvvtuiQ3oJKl69eoKCgrS66+/rh9//FHz5s3TmDFjPJb5+eef9cADD+j555/XNddco8mTJ2vs2LH65ptvvK7z5Zdf1gcffKDvv/9emzdv1uzZsxUdHa2IiIiy3EUAAC54hHYAAC5RFStWVK9evVShQgX17NmzxOWqVKmilJQUzZ49W40aNdL48eM1YcIE93xjjPr376+rrrpKycnJkqQuXbrogQce0B133KGDBw8WW2dYWJheeOEFtWrVSq1bt9b27du1YMECr53mAQC4lLmMMcbXRQAAAN/o2LGjGjdurIkTJ/q6FAAA4AWhHQCAS9DevXuVlpamW265RZs2bVL9+vV9XRIAAPCCRnQAAFyC4uPjtXfvXj3//PMEdgAAHIwj7QAAAAAAOBTdXgAAAAAAcChCOwAAAAAADkVoBwAAAADAoQjtAAAAAAA4FKEdAAAAAACHIrQDAAAAAOBQhHYAAAAAAByK0A4AAAAAgEMR2gEAAAAAcKj/A2KbkLMKT+JgAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1200x800 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(12,8))\n",
    "\n",
    "## User locations\n",
    "active_bs_idx = 0 # Select the first active basestation in the dataset\n",
    "plt.scatter(DeepMIMO_dataset[active_bs_idx]['user']['location'][:, 1], # y-axis location of the users\n",
    "         DeepMIMO_dataset[active_bs_idx]['user']['location'][:, 0], # x-axis location of the users\n",
    "         s=1, marker='x', c='C0', label='The users located on the rows %i to %i (R%i to R%i)'%\n",
    "           (DeepMIMO_params['user_row_first'], DeepMIMO_params['user_row_last'],\n",
    "           DeepMIMO_params['user_row_first'], DeepMIMO_params['user_row_last']))\n",
    "# First 181 users correspond to the first row\n",
    "plt.scatter(DeepMIMO_dataset[active_bs_idx]['user']['location'][0:181, 1],\n",
    "         DeepMIMO_dataset[active_bs_idx]['user']['location'][0:181, 0],\n",
    "         s=1, marker='x', c='C1', label='First row of users (R%i)'% (DeepMIMO_params['user_row_first']))\n",
    "\n",
    "## Basestation location\n",
    "plt.scatter(DeepMIMO_dataset[active_bs_idx]['location'][1],\n",
    "         DeepMIMO_dataset[active_bs_idx]['location'][0],\n",
    "         s=50.0, marker='o', c='C2', label='Basestation')\n",
    "\n",
    "plt.gca().invert_xaxis() # Invert the x-axis to align the figure with the figure above\n",
    "plt.ylabel('x-axis')\n",
    "plt.xlabel('y-axis')\n",
    "plt.grid()\n",
    "plt.legend();"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Using DeepMIMO with Sionna\n",
    "\n",
    "The DeepMIMO Python package provides [a Sionna-compliant channel impulse response generator](https://nvlabs.github.io/sionna/phy/tutorials/CIR_Dataset.html#Generators) that adapts the structure of the DeepMIMO dataset to be consistent with Sionna.\n",
    "\n",
    "An adapter is instantiated for a given DeepMIMO dataset. In addition to the dataset, the adapter takes the indices of the basestations and users, to generate the channels between these basestations and users:\n",
    "\n",
    "`DeepMIMOSionnaAdapter(DeepMIMO_dataset, bs_idx, ue_idx)`\n",
    "\n",
    "\n",
    "**Note:** `bs_idx` and `ue_idx` set the links from which the channels are drawn. For instance, if `bs_idx = [0, 1]` and `ue_idx = [2, 3]`, the adapter then outputs the 4 channels formed by the combination of the first and second basestations with the third and fourth users.\n",
    "\n",
    "The default behavior for `bs_idx` and `ue_idx` are defined as follows:\n",
    "- If value for `bs_idx` is not given, it will be set to `[0]` (i.e., the first basestation in the `DeepMIMO_dataset`).\n",
    "- If value for `ue_idx` is not given, then channels are provided for the links between the `bs_idx` and all users (i.e., `ue_idx=range(len(DeepMIMO_dataset[0]['user']['channel']))`.\n",
    "- If the both `bs_idx` and `ue_idx` are not given, the channels between the first basestation and all the users are provided by the adapter. For this example, `DeepMIMOSionnaAdapter(DeepMIMO_dataset)` returns the channels from the basestation 6 and the 9231 available user locations.\n",
    "\n",
    "**Note:** The adapter assumes basestations are transmitters and users are receivers. Uplink channels can be obtained using (transpose) reciprocity.\n",
    "\n",
    "### Random Sampling of Multi-User Channels\n",
    "\n",
    "When considering multiple basestations, `bs_idx` can be set to a 2D numpy matrix of shape $($ # of samples $\\times$ # of basestations per sample $)$. In this case, for each sample of basestations, the `DeepMIMOSionnaAdapter` returns a set of $($ # of basestations per sample $\\times$ # of users $)$ channels, which can be provided as a multi-transmitter sample for the Sionna model. For example, `bs_idx = np.array([[0, 1], [2, 3], [4, 5]])` provides three sets of $($ 2 basestations $\\times$ # of users $)$ channels. These three channel sets are from the basestation sets `[0, 1]`, `[2, 3]`, and `[4, 5]`, respectively, to the users.\n",
    "\n",
    "To use the adapter for multi-user channels, `ue_idx` can be set to a 2D numpy matrix of shape $($ # of samples $\\times$ # of users per sample $)$. In this case, for each sample of users, the `DeepMIMOSionnaAdapter` returns a set of $($ # of basestations $\\times$ # of users per sample $)$ channels, which can be provided as a multi-receiver sample for the Sionna model. For example, `ue_idx = np.array([[0, 1 ,2], [4, 5, 6]])` provides two sets of $($ # of basestations $\\times$ 3 users $)$ channels. These two channel sets are from the basestations to the user sets `[0, 1, 2]` and `[4, 5, 6]`, respectively.\n",
    "\n",
    "In order to randomly sample channels from all the available user locations considering `num_rx` users, one may set `ue_idx` as in the following cell. In this example, the channels will be randomly chosen from the links between the basestation 6 and the 9231 available user locations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-03-13T01:48:52.376377Z",
     "iopub.status.busy": "2025-03-13T01:48:52.376179Z",
     "iopub.status.idle": "2025-03-13T01:48:52.380757Z",
     "shell.execute_reply": "2025-03-13T01:48:52.380192Z"
    }
   },
   "outputs": [],
   "source": [
    "from DeepMIMO import DeepMIMOSionnaAdapter\n",
    "\n",
    "# Number of receivers for the Sionna model.\n",
    "# MISO is considered here.\n",
    "num_rx = 1\n",
    "\n",
    "# The number of UE locations in the generated DeepMIMO dataset\n",
    "num_ue_locations = len(DeepMIMO_dataset[0]['user']['channel']) # 9231\n",
    "# Pick the largest possible number of user locations that is a multiple of ``num_rx``\n",
    "ue_idx = np.arange(num_rx*(num_ue_locations//num_rx))\n",
    "# Optionally shuffle the dataset to not select only users that are near each others\n",
    "np.random.shuffle(ue_idx)\n",
    "# Reshape to fit the requested number of users\n",
    "ue_idx = np.reshape(ue_idx, [-1, num_rx]) # In the shape of (floor(9231/num_rx) x num_rx)\n",
    "\n",
    "DeepMIMO_Sionna_adapter = DeepMIMOSionnaAdapter(DeepMIMO_dataset, ue_idx=ue_idx)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Link-level Simulations using Sionna and DeepMIMO\n",
    "\n",
    "In the following cell, we define a Sionna model implementing the end-to-end link.\n",
    "\n",
    "**Note:** The Sionna CIRDataset object shuffles the DeepMIMO channels provided by the adapter. Therefore, channel samples are passed through the model in a random order."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-03-13T01:48:52.384454Z",
     "iopub.status.busy": "2025-03-13T01:48:52.384238Z",
     "iopub.status.idle": "2025-03-13T01:48:52.397002Z",
     "shell.execute_reply": "2025-03-13T01:48:52.396376Z"
    }
   },
   "outputs": [],
   "source": [
    "class LinkModel(Block):\n",
    "    def __init__(self,\n",
    "                 DeepMIMO_Sionna_adapter,\n",
    "                 carrier_frequency,\n",
    "                 cyclic_prefix_length,\n",
    "                 pilot_ofdm_symbol_indices,\n",
    "                 subcarrier_spacing = 60e3,\n",
    "                 batch_size = 64\n",
    "                ):\n",
    "        super().__init__()\n",
    "\n",
    "        self._batch_size = batch_size\n",
    "        self._cyclic_prefix_length = cyclic_prefix_length\n",
    "        self._pilot_ofdm_symbol_indices = pilot_ofdm_symbol_indices\n",
    "\n",
    "        # CIRDataset to parse the dataset\n",
    "        self._CIR = CIRDataset(DeepMIMO_Sionna_adapter,\n",
    "                               self._batch_size,\n",
    "                               DeepMIMO_Sionna_adapter.num_rx,\n",
    "                               DeepMIMO_Sionna_adapter.num_rx_ant,\n",
    "                               DeepMIMO_Sionna_adapter.num_tx,\n",
    "                               DeepMIMO_Sionna_adapter.num_tx_ant,\n",
    "                               DeepMIMO_Sionna_adapter.num_paths,\n",
    "                               DeepMIMO_Sionna_adapter.num_time_steps)\n",
    "\n",
    "        # System parameters\n",
    "        self._carrier_frequency = carrier_frequency\n",
    "        self._subcarrier_spacing = subcarrier_spacing\n",
    "        self._fft_size = 76\n",
    "        self._num_ofdm_symbols = 14\n",
    "        self._num_streams_per_tx = DeepMIMO_Sionna_adapter.num_rx\n",
    "        self._dc_null = False\n",
    "        self._num_guard_carriers = [0, 0]\n",
    "        self._pilot_pattern = \"kronecker\"\n",
    "        self._pilot_ofdm_symbol_indices = pilot_ofdm_symbol_indices\n",
    "        self._num_bits_per_symbol = 4\n",
    "        self._coderate = 0.5\n",
    "\n",
    "        # Setup the OFDM resource grid and stream management\n",
    "        self._sm = StreamManagement(np.ones([DeepMIMO_Sionna_adapter.num_rx, 1], int), self._num_streams_per_tx)\n",
    "        self._rg = ResourceGrid(num_ofdm_symbols=self._num_ofdm_symbols,\n",
    "                                fft_size=self._fft_size,\n",
    "                                subcarrier_spacing = self._subcarrier_spacing,\n",
    "                                num_tx=DeepMIMO_Sionna_adapter.num_tx,\n",
    "                                num_streams_per_tx=self._num_streams_per_tx,\n",
    "                                cyclic_prefix_length=self._cyclic_prefix_length,\n",
    "                                num_guard_carriers=self._num_guard_carriers,\n",
    "                                dc_null=self._dc_null,\n",
    "                                pilot_pattern=self._pilot_pattern,\n",
    "                                pilot_ofdm_symbol_indices=self._pilot_ofdm_symbol_indices)\n",
    "\n",
    "        # Components forming the link\n",
    "\n",
    "        # Codeword length\n",
    "        self._n = int(self._rg.num_data_symbols * self._num_bits_per_symbol)\n",
    "        # Number of information bits per codeword\n",
    "        self._k = int(self._n * self._coderate)\n",
    "\n",
    "        # OFDM channel\n",
    "        self._frequencies = subcarrier_frequencies(self._rg.fft_size, self._rg.subcarrier_spacing)\n",
    "        self._ofdm_channel = GenerateOFDMChannel(self._CIR, self._rg, normalize_channel=True)\n",
    "        self._channel_freq = ApplyOFDMChannel(add_awgn=True)\n",
    "\n",
    "        # Transmitter\n",
    "        self._binary_source = BinarySource()\n",
    "        self._encoder = LDPC5GEncoder(self._k, self._n)\n",
    "        self._mapper = Mapper(\"qam\", self._num_bits_per_symbol)\n",
    "        self._rg_mapper = ResourceGridMapper(self._rg)\n",
    "        self._zf_precoder = RZFPrecoder(self._rg, self._sm, return_effective_channel=True)\n",
    "\n",
    "        # Receiver\n",
    "        self._ls_est = LSChannelEstimator(self._rg, interpolation_type=\"lin_time_avg\")\n",
    "        self._lmmse_equ = LMMSEEqualizer(self._rg, self._sm)\n",
    "        self._demapper = Demapper(\"app\", \"qam\", self._num_bits_per_symbol)\n",
    "        self._decoder = LDPC5GDecoder(self._encoder, hard_out=True)\n",
    "        self._remove_nulled_scs = RemoveNulledSubcarriers(self._rg)\n",
    "\n",
    "    def call(self, batch_size, ebno_db):\n",
    "\n",
    "        # Transmitter\n",
    "        b = self._binary_source([self._batch_size, 1, self._num_streams_per_tx, self._k])\n",
    "        c = self._encoder(b)\n",
    "        x = self._mapper(c)\n",
    "        x_rg = self._rg_mapper(x)\n",
    "        # Generate the OFDM channel\n",
    "        h_freq = self._ofdm_channel()\n",
    "        # Precoding\n",
    "        x_rg, g = self._zf_precoder(x_rg, h_freq)\n",
    "\n",
    "        # Apply OFDM channel\n",
    "        no = ebnodb2no(ebno_db, self._num_bits_per_symbol, self._coderate, self._rg)\n",
    "        y = self._channel_freq(x_rg, h_freq, no)\n",
    "\n",
    "        # Receiver\n",
    "        h_hat, err_var = self._ls_est (y, no)\n",
    "        x_hat, no_eff = self._lmmse_equ(y, h_hat, err_var, no)\n",
    "        llr = self._demapper(x_hat, no_eff)\n",
    "        b_hat = self._decoder(llr)\n",
    "\n",
    "        return b, b_hat"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We next evaluate the setup with different $E_b/N_0$ values to obtain BLER curves."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-03-13T01:48:52.400127Z",
     "iopub.status.busy": "2025-03-13T01:48:52.399905Z",
     "iopub.status.idle": "2025-03-13T01:49:23.855650Z",
     "shell.execute_reply": "2025-03-13T01:49:23.854765Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "EbNo [dB] |        BER |       BLER |  bit errors |    num bits | block errors |  num blocks | runtime [s] |    status\n",
      "---------------------------------------------------------------------------------------------------------------------------------------\n",
      "     -7.0 | 1.2337e-01 | 1.0000e+00 |       28803 |      233472 |          128 |         128 |         7.4 |reached target block errors\n",
      "   -6.806 | 9.1728e-02 | 9.9219e-01 |       21416 |      233472 |          127 |         128 |         0.1 |reached target block errors\n",
      "   -6.611 | 6.0393e-02 | 9.3750e-01 |       14100 |      233472 |          120 |         128 |         0.1 |reached target block errors\n",
      "   -6.417 | 2.7489e-02 | 7.6562e-01 |        9627 |      350208 |          147 |         192 |         0.1 |reached target block errors\n",
      "   -6.222 | 6.6111e-03 | 3.9844e-01 |        3087 |      466944 |          102 |         256 |         0.2 |reached target block errors\n",
      "   -6.028 | 9.2416e-04 | 9.9265e-02 |        1834 |     1984512 |          108 |        1088 |         0.9 |reached target block errors\n",
      "   -5.833 | 7.8896e-05 | 1.3594e-02 |         921 |    11673600 |           87 |        6400 |         5.1 |reached max iterations\n",
      "   -5.639 | 9.8513e-06 | 2.0313e-03 |         115 |    11673600 |           13 |        6400 |         5.2 |reached max iterations\n",
      "   -5.444 | 4.2832e-07 | 1.5625e-04 |           5 |    11673600 |            1 |        6400 |         5.2 |reached max iterations\n",
      "    -5.25 | 0.0000e+00 | 0.0000e+00 |           0 |    11673600 |            0 |        6400 |         5.1 |reached max iterations\n",
      "\n",
      "Simulation stopped as no error occurred @ EbNo = -5.2 dB.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "sim_params = {\n",
    "              \"ebno_db\": np.linspace(-7, -5.25, 10),\n",
    "              \"cyclic_prefix_length\" : 0,\n",
    "              \"pilot_ofdm_symbol_indices\" : [2, 11],\n",
    "              }\n",
    "batch_size = 64\n",
    "model = LinkModel(DeepMIMO_Sionna_adapter=DeepMIMO_Sionna_adapter,\n",
    "                  carrier_frequency=DeepMIMO_params['scenario_params']['carrier_freq'],\n",
    "                  cyclic_prefix_length=sim_params[\"cyclic_prefix_length\"],\n",
    "                  pilot_ofdm_symbol_indices=sim_params[\"pilot_ofdm_symbol_indices\"])\n",
    "ber, bler = sim_ber(model,\n",
    "                    sim_params[\"ebno_db\"],\n",
    "                    batch_size=batch_size,\n",
    "                    max_mc_iter=100,\n",
    "                    num_target_block_errors=100,\n",
    "                    graph_mode=\"graph\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-03-13T01:49:23.859850Z",
     "iopub.status.busy": "2025-03-13T01:49:23.859631Z",
     "iopub.status.idle": "2025-03-13T01:49:24.255402Z",
     "shell.execute_reply": "2025-03-13T01:49:24.254518Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f541c4572e0>]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 1200x800 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(12,8))\n",
    "plt.xlabel(r\"$E_b/N_0$ (dB)\")\n",
    "plt.ylabel(\"BLER\")\n",
    "plt.grid(which=\"both\")\n",
    "plt.semilogy(sim_params[\"ebno_db\"], bler)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## DeepMIMO License and Citation\n",
    "\n",
    "A. Alkhateeb, “[DeepMIMO: A Generic Deep Learning Dataset for Millimeter Wave and Massive MIMO Applications](https://arxiv.org/pdf/1902.06435.pdf),” in Proc. of Information Theory and Applications Workshop (ITA), San Diego, CA, Feb. 2019.\n",
    "\n",
    "To use the DeepMIMO dataset, please check the license information [here](https://deepmimo.net/license/)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.16"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
